const { MemberLevel, User } = require('../models');
const { Op } = require('sequelize');
const logger = require('../utils/logger');

class MemberLevelService {
  /**
   * 创建会员等级
   * @param {Object} data - 会员等级数据
   * @returns {Promise<MemberLevel>} - 创建后的会员等级
   */
  async createMemberLevel(data) {
    try {
      const memberLevel = await MemberLevel.create(data);
      logger.info(`Member level created with ID: ${memberLevel.id}`);
      return memberLevel;
    } catch (error) {
      logger.error('Error creating member level:', error);
      throw error;
    }
  }

  /**
   * 获取会员等级
   * @param {Object} filters - 过滤条件
   * @returns {Promise<Array<MemberLevel>>} - 会员等级列表
   */
  async getMemberLevels(filters = {}) {
    try {
      const where = {};
      if (filters.status) {
        where.status = filters.status;
      }
      if (filters.search) {
        where[Op.or] = [
          { name: { [Op.like]: `%${filters.search}%` } },
          { description: { [Op.like]: `%${filters.search}%` } }
        ];
      }

      const memberLevels = await MemberLevel.findAll({
        where,
        order: [['level', 'ASC']]
      });
      return memberLevels;
    } catch (error) {
      logger.error('Error getting member levels:', error);
      throw error;
    }
  }

  /**
   * 获取会员等级
   * @param {number} id - 会员等级ID
   * @returns {Promise<MemberLevel>} - 会员等级
   */
  async getMemberLevelById(id) {
    try {
      const memberLevel = await MemberLevel.findByPk(id);
      if (!memberLevel) {
        throw new Error('Member level not found');
      }
      return memberLevel;
    } catch (error) {
      logger.error(`Error getting member level with ID ${id}:`, error);
      throw error;
    }
  }

  /**
   * 更新会员等级
   * @param {number} id - 会员等级ID
   * @param {Object} data - 更新数据
   * @returns {Promise<MemberLevel>} - 更新后的会员等级
   */
  async updateMemberLevel(id, data) {
    try {
      const memberLevel = await this.getMemberLevelById(id);
      await memberLevel.update(data);
      logger.info(`Member level ${id} updated successfully`);
      return memberLevel;
    } catch (error) {
      logger.error(`Error updating member level ${id}:`, error);
      throw error;
    }
  }

  /**
   * 删除会员等级
   * @param {number} id - 会员等级ID
   * @returns {Promise<boolean>} - 删除结果
   */
  async deleteMemberLevel(id) {
    try {
      const memberLevel = await this.getMemberLevelById(id);
      await memberLevel.destroy();
      logger.info(`Member level ${id} deleted successfully`);
      return true;
    } catch (error) {
      logger.error(`Error deleting member level ${id}:`, error);
      throw error;
    }
  }

  /**
   * 更新会员等级状态
   * @param {number} id - 会员等级ID
   * @param {string} status - 状态
   * @returns {Promise<MemberLevel>} - 更新后的会员等级
   */
  async updateMemberLevelStatus(id, status) {
    try {
      const memberLevel = await this.getMemberLevelById(id);
      await memberLevel.update({ status });
      logger.info(`Member level ${id} status updated to ${status}`);
      return memberLevel;
    } catch (error) {
      logger.error(`Error updating member level ${id} status:`, error);
      throw error;
    }
  }

  /**
   * 获取会员等级用户
   * @param {number} id - 会员等级ID
   * @param {number} page - 页码
   * @param {number} limit - 每页数量
   * @returns {Promise<Object>} - 用户列表和分页信息
   */
  async getMemberLevelUsers(id, page = 1, limit = 10) {
    try {
      const offset = (page - 1) * limit;
      const memberLevel = await this.getMemberLevelById(id);
      const users = await User.findAndCountAll({
        where: { memberLevelId: id },
        attributes: ['id', 'name', 'email', 'phone', 'totalPoints', 'memberLevelId'],
        limit,
        offset,
        order: [['totalPoints', 'DESC']]
      });

      return {
        level: memberLevel,
        users: users.rows,
        total: users.count,
        page,
        totalPages: Math.ceil(users.count / limit)
      };
    } catch (error) {
      logger.error(`Error getting users for member level ${id}:`, error);
      throw error;
    }
  }

  /**
   * 检查用户等级升级
   * @param {number} userId - 用户ID
   * @returns {Promise<Object>} - 升级结果
   */
    async checkUserLevelUpgrade(userId) {
    try {
      const user = await User.findByPk(userId);
      if (!user) {
        throw new Error('User not found');
      }

      // Get all active levels ordered by points required
      const levels = await MemberLevel.findAll({
        where: { status: 'active' },
        order: [['pointsRequired', 'ASC']]
      });

      // Find the highest level the user qualifies for
      let appropriateLevel = null;
      for (const level of levels) {
        if (user.totalPoints >= level.pointsRequired) {
          appropriateLevel = level;
        } else {
          break;
        }
      }

      if (!appropriateLevel) {
        return {
          upgraded: false,
          reason: 'User does not qualify for any level'
        };
      }

      // Check if user needs to be upgraded
      if (user.memberLevelId !== appropriateLevel.id) {
        const oldLevel = user.memberLevelId ? 
          await this.getMemberLevelById(user.memberLevelId) : null;

        await user.update({ memberLevelId: appropriateLevel.id });

        return {
          upgraded: true,
          oldLevel,
          newLevel: appropriateLevel,
          pointsRequired: appropriateLevel.pointsRequired,
          userPoints: user.totalPoints
        };
      }

      return {
        upgraded: false,
        reason: 'User is already at the appropriate level'
      };
    } catch (error) {
      logger.error(`Error checking level upgrade for user ${userId}:`, error);
      throw error;
    }
  }

  /**
   * 获取用户下一个等级
   * @param {number} userId - 用户ID
   * @returns {Promise<Object>} - 下一个等级信息
   */
  async getUserNextLevel(userId) {
    try {
      const user = await User.findByPk(userId, {
        include: [{
          model: MemberLevel,
          attributes: ['id', 'name', 'level', 'pointsRequired']
        }]
      });

      if (!user) {
        throw new Error('User not found');
      }

      // Get the next level
      const nextLevel = await MemberLevel.findOne({
        where: {
          status: 'active',
          pointsRequired: {
            [Op.gt]: user.totalPoints
          }
        },
        order: [['pointsRequired', 'ASC']]
      });

      if (!nextLevel) {
        return {
          currentLevel: user.MemberLevel,
          nextLevel: null,
          pointsToNextLevel: 0,
          isMaxLevel: true
        };
      }

      return {
        currentLevel: user.MemberLevel,
        nextLevel,
        pointsToNextLevel: nextLevel.pointsRequired - user.totalPoints,
        isMaxLevel: false
      };
    } catch (error) {
      logger.error(`Error getting next level for user ${userId}:`, error);
      throw error;
    }
  }

  /**
   * 获取等级进度统计
   * @returns {Promise<Object>} - 等级进度统计
   */
  async getLevelProgressionStats() {
    try {
      const usersPerLevel = await User.count({
        group: ['memberLevelId'],
        include: [{
          model: MemberLevel,
          attributes: ['name', 'level']
        }]
      });

      const averagePointsPerLevel = await User.findAll({
        attributes: [
          'memberLevelId',
          [User.sequelize.fn('AVG', User.sequelize.col('totalPoints')), 'averagePoints'],
          [User.sequelize.fn('COUNT', '*'), 'userCount']
        ],
        group: ['memberLevelId'],
        include: [{
          model: MemberLevel,
          attributes: ['name', 'level']
        }]
      });

      return {
        usersPerLevel,
        averagePointsPerLevel
      };
    } catch (error) {
      logger.error('Error getting level progression stats:', error);
      throw error;
    }
  }
}

module.exports = new MemberLevelService(); 